#ifndef GTL_CONCURRENCY_ATOMIC_HEADER_GUARD
#define GTL_CONCURRENCY_ATOMIC_HEADER_GUARD

namespace GTL
{
  namespace Concurrency
  {

/// inne interlocki:
/// http://www.boost.org/doc/libs/1_39_0/boost/interprocess/detail/atomic.hpp
/// http://www.boost.org/doc/libs/1_39_0/boost/detail/interlocked.hpp

#ifdef GTL_COMPILER_VISUAL_STUDIO

  #define GTL_ATOMIC_INCREMENT InterlockedIncrement
  #define GTL_ATOMIC_DECREMENT InterlockedDecrement
  #define GTL_ATOMIC_COMPARE_AND_EXCHANGE(d,c,e) InterlockedCompareExchange((LONG volatile*)d,(LONG)e,(LONG)c)
  //#define GTL_ATOMIC_INCREMENT InterlockedIncrement

  extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volatile * );
  extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * );
  extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long );
  //extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long );
  //extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long volatile *, long );

  #if GTL_64_BIT_COMPILER
    extern "C" __declspec(dllimport) void* __stdcall InterlockedCompareExchangePointer( void* volatile *, void*, void* );
    #define GTL_ATOMIC_COMPARE_AND_EXCHANGE_POINTER(d,c,e) InterlockedCompareExchangePointer(d,e,c)
  #else
    #define GTL_ATOMIC_COMPARE_AND_EXCHANGE_POINTER(dest,compare,exchange) \
      ((void*)InterlockedCompareExchange((long volatile*)(dest),(long)(exchange),(long)(compare)))
  #endif

#elif GTL_COMPILER_GCC_X86

  inline void* GTL_ATOMIC_COMPARE_AND_EXCHANGE_POINTER(void** destination, void* comp, void* exch)
  {
    void* prev = comp;
    asm volatile( "lock\n\t"
      "cmpxchg %3,%1"
      : "=a" (prev), "=m" (*(destination))
      : "0" (prev), "r" (exch)
      : "memory", "cc");
    return prev;
  }

#elif GTL_COMPILER_IOS

#include <libkern/OSAtomic.h>

inline void* GTL_ATOMIC_COMPARE_AND_EXCHANGE_POINTER(void* volatile* destination, void* comp, void* exch)
{
  // OSAtomicCompareAndSwapPtr(void* oldValue, void* newValue, void* volatile *theValue);
  void* prev = comp;
  OSAtomicCompareAndSwapPtr(comp, exch, destination);
  return prev;
}

#endif
  }
}

#endif